/**
 * Collaborative Story Development Web Application (CSDApp) 
 * Copyright Anton Strack 2014
 *
 * This file is part of Collaborative Story Development Application (CSDApp).
 *
 * CSDApp is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or any later version.
 *
 * CSDApp is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * CSDApp. If not, see <http://www.gnu.org/licenses/>.
 *
 */
package csdwa;

import java.sql.Timestamp;

/**
 * This class contains the information that is displayed to the end user when
 * they get a notification about an event. This bean is built with information
 * from the notification type table as well as notification mailbox table and
 * with information from the resource the event occurred on.
 *
 *
 * @author Anton Strack
 */
public class Notification extends Resource {

    /**
     * The user id of the mailbox owner. The id of who will see this specific
     * notification.
     */
    private int UserId;
    /**
     * The notification template type id. This id is used to build the
     * notification to display for the user.
     */
    private int NotificationTypeId;
    /**
     * The resource id pointing to the specific resource the event occurred on
     * that triggered the notification.
     */
    private int resourceId;
    /**
     * The state of the notification in the notification mailbox.
     */
    private int stateId;
    /**
     * The user id of who preformed the action on the resource that triggered
     * this notification.
     */
    private int eventCreatorId;
    /**
     * The date this notification was created in the user's notification mailbox
     * and thus the date the event occurred.
     */
    private Timestamp notificationDate;
    /**
     * The template object the notification is partially built from.
     */
    private NotificationTemplate template;
    /**
     * The name of the resource the notification is about. Due to the nature of
     * resources being spread across different domain tables, there is no
     * non-convoluted way to retrieve the resource's name from a single query
     * statement, as there is potentially six different tables to choose from.
     * Thus, just save the resource's name in the notification row.
     */
    private String resourceName;

    /**
     * Construct an empty notification object. This constructor is provided so
     * the class can be a java bean but it shouldn't be instantiated with this
     * constructor in normal code as it doesn't set the resourceTypeId;
     */
    public Notification() {
    }

    /**
     * Construct the notification object in its minium working state.
     *
     * @param resourceTypeId the type of resource the notification object is
     * from the application's point of view.
     */
    public Notification(int resourceTypeId) {
        this.resourceTypeId = resourceTypeId;
    }

    /**
     * The user id of the mailbox owner. The id of who will see this specific
     * notification.
     *
     * @return the UserId
     */
    public int getUserId() {
        return UserId;
    }

    /**
     * The user id of the mailbox owner. The id of who will see this specific
     * notification.
     *
     * @param UserId the UserId to set
     */
    public void setUserId(int UserId) {
        this.UserId = UserId;
    }

    /**
     * The notification template type id. This id is used to build the
     * notification to display for the user.
     *
     * @return the NotificationTypeId
     */
    public int getNotificationTypeId() {
        return NotificationTypeId;
    }

    /**
     * The notification template type id. This id is used to build the
     * notification to display for the user.
     *
     * @param NotificationTypeId the NotificationTypeId to set
     */
    public void setNotificationTypeId(int NotificationTypeId) {
        this.NotificationTypeId = NotificationTypeId;
    }

    /**
     * The resource id pointing to the specific resource the event occurred on
     * that triggered the notification.
     *
     * @return the resourceId
     */
    public int getResourceId() {
        return resourceId;
    }

    /**
     * The resource id pointing to the specific resource the event occurred on
     * that triggered the notification.
     *
     * @param resourceId the resourceId to set
     */
    public void setResourceId(int resourceId) {
        this.resourceId = resourceId;
    }

    /**
     * The state of the notification in the notification mailbox.
     *
     * @return the stateId
     */
    public int getStateId() {
        return stateId;
    }

    /**
     * The state of the notification in the notification mailbox.
     *
     * @param stateId the stateId to set
     */
    public void setStateId(int stateId) {
        this.stateId = stateId;
    }

    /**
     * The user id of who preformed the action on the resource that triggered
     * this notification.
     *
     * @return the eventCreatorId
     */
    public int getEventCreatorId() {
        return eventCreatorId;
    }

    /**
     * The user id of who preformed the action on the resource that triggered
     * this notification.
     *
     * @param eventCreatorId the eventCreatorId to set
     */
    public void setEventCreatorId(int eventCreatorId) {
        this.eventCreatorId = eventCreatorId;
    }

    /**
     * The date this notification was created in the user's notification mailbox
     * and thus the date the event occurred.
     *
     * @return the notificationDate
     */
    public Timestamp getNotificationDate() {
        return notificationDate;
    }

    /**
     * The date this notification was created in the user's notification mailbox
     * and thus the date the event occurred.
     *
     * @param notificationDate the notificationDate to set
     */
    public void setNotificationDate(Timestamp notificationDate) {
        this.notificationDate = notificationDate;
    }

    /**
     * The template object the notification is partially built from.
     *
     * @return the template
     */
    public NotificationTemplate getTemplate() {
        return template;
    }

    /**
     * The template object the notification is partially built from.
     *
     * @param template the template to set
     */
    public void setTemplate(NotificationTemplate template) {
        this.template = template;
    }

    /**
     * The name of the resource the notification is about.
     *
     * @return the resourceName
     */
    public String getResourceName() {
        return resourceName;
    }

    /**
     * The name of the resource the notification is about.
     *
     * @param resourceName the resourceName to set
     */
    public void setResourceName(String resourceName) {
        this.resourceName = resourceName;
    }

    @Override
    public String toString() {
        return "Notification{" + "UserId=" + UserId + ", NotificationTypeId=" + NotificationTypeId + ", resourceId=" + resourceId + ", stateId=" + stateId + ", eventCreatorId=" + eventCreatorId + ", notificationDate=" + notificationDate + ", notificationTemplate=" + template + ", resourceName=" + resourceName + '}' + super.toString();
    }

    /**
     * Get the derived string value matching the key. Derived values are values
     * not stored in the bean's database table. They are either the matching
     * names of id values stored in the bean table or they are other related
     * values. This method first checks its own derived values map for the value
     * no value is found and this objects NotificationTemplate object isn't
     * null, then it checks its derived value map for the key and returns it or
     * and empty string.
     *
     * @param key Column name key for retrieving the derived attribute. As long
     * as setDerivedValue() was used to set the derived value, case does not
     * matter for the key.
     * @return the derived attribute value matching the key or an empty string
     * if the key doesn't exist.
     */
    @Override
    public String getDerivedValue(String key) {
        key = key.toLowerCase();
        String value = super.getDerivedValue(key);
        if (value.isEmpty() && this.template != null) {
            if (this.template.getDerivedValue(key) != null) {
                return this.template.getDerivedValue(key);
            }
        } else {
            return value;
        }
        return "";
    }

    /**
     * Get the derived int value matching the key. Derived values are values not
     * stored in the bean's database table. They are either the matching names
     * of id values stored in the bean table or they are other related values.
     * This method attempts to return the derived value as an integer. This
     * method first checks its own derived values map for the value no value is
     * found and this objects NotificationTemplate object isn't null, then it
     * checks its derived value map for the key and returns it or and empty
     * string.
     *
     * @param key Column name key for retrieving the derived attribute. As long
     * as setDerivedValue() was used to set the derived value, case does not
     * matter for the key.
     * @return the derived attribute value matching the key or 0 if the key
     * doesn't exist
     */
    @Override
    public int getDerivedInt(String key) {
        int value;
        key = key.toLowerCase();
        value = super.getDerivedInt(key);
        if (value == 0) {
            value = this.getTemplate().getDerivedInt(key);
        }
        // return zero if any above condition fails
        return value;
    }
}
